package cn.edu.aynu;

import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.Set;
import java.util.stream.Stream;

import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.Query;
import javax.servlet.ServletContext;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import com.alibaba.druid.pool.DruidDataSource;

import cn.edu.aynu.common.DataBaseInit;
import cn.edu.aynu.mapper.SqlMapper;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 * Spring在启动完成后执行方法
 * 
 * @author 00fly
 * @version [版本号, 2018年7月31日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Slf4j
@Component
public class Startup implements ApplicationListener<ContextRefreshedEvent>
{
    @Autowired
    SqlMapper sqlMapper;
    
    @Autowired
    DruidDataSource dataSource;
    
    @Autowired
    ServletContext servletContext;
    
    /**
     * DataBaseInit正式刷表前可按需自动建库
     * 
     * @throws IOException
     * @see [类、类#方法、类#成员]
     */
    // @PostConstruct
    public void init()
        throws IOException
    {
        log.info("执行初始化刷表");
        try (InputStream inputStream = Startup.class.getResourceAsStream("/sql/init.sql"))
        {
            String sqlText = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
            log.info("SQL = {}", sqlText);
            log.info("开始分割执行当前的初始化语句块");
            Stream.of(sqlText.split(";")).filter(StringUtils::isNotBlank).forEach(sqlMapper::execute);
            log.info("★★★★ execute success!!");
        }
    }
    
    /**
     * 事件回调
     * 
     * @param event
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event)
    {
        ApplicationContext applicationContext = event.getApplicationContext();
        log.info("★★★★★★★★ {}", applicationContext);
        log.info("★★★★ JDBC_URL: {}", dataSource.getRawJdbcUrl());
        
        // servlet context初始化完成
        if (applicationContext.getParent() != null && SystemUtils.IS_OS_WINDOWS)
        {
            try
            {
                DataBaseInit.initUseSQL("/sql/init.sql");
                
                log.info("now open Browser...");
                String ip = InetAddress.getLocalHost().getHostAddress();
                String url = "http://" + ip + ":" + getTomcatPort() + servletContext.getContextPath();
                Runtime.getRuntime().exec("cmd /c start /min " + url + "/customer/list");
            }
            catch (Exception e)
            {
                log.error(e.getMessage(), e);
            }
        }
    }
    
    /**
     * 获取tomcat启动端口（****注意非tomcat服务器获取不到，返回默认值8080）
     * 
     * @return
     * @throws MalformedObjectNameException
     * @see [类、类#方法、类#成员]
     */
    private int getTomcatPort()
        throws MalformedObjectNameException
    {
        MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
        Set<ObjectName> objectNames = beanServer.queryNames(new ObjectName("*:type=Connector,*"), Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
        String port = null;
        if (objectNames.iterator().hasNext())
        {
            port = objectNames.iterator().next().getKeyProperty("port");
        }
        return NumberUtils.toInt(port, 8080);
    }
    
}
